package XMFramework.Interface.Architechture
{
	import XMFramework.Interface.IFramework;
	import XMFramework.Interface.IResources;
	
	import flash.display.DisplayObjectContainer;
	import flash.display.Graphics;
	import flash.display.Sprite;
	
	/**
	 * 
	 * @author THANHQUOC
	 * 
	 */	
	public class SMUIBase extends Sprite
	{
		/**
		 * Save view display information 
		 */		
		protected var _parentContainer : DisplayObjectContainer	=	null;		
		
		/**
		 * Pointer to singleton SNS framework object 
		 */		
		public var coreSNSFramework : IFramework;
		
		/**
		 * Reference pointer to collerate Command tire 
		 * @return 
		 * 
		 */		
		public var commandLayer : SMController	=	null;
		
		/**
		 * Reference pointer to collerate model tire  
		 * @return 
		 * 
		 */		
		public var modelLayer : SMModel	=	null;
		
		/**
		 * Reference pointer to collerate view tire  
		 * @return 
		 * 
		 */		
		public var viewLayer : SMView	=	null;
		
		/**
		 * 
		 */		
		private var isAddToParent : Boolean;
		
		//////////////////////////////////////////////////////
		
		/**
		 * Constructor 
		 * 
		 */		
		public function SMUIBase()
		{
			super();
		}
		
		//////////////////////////////////////////////////////
		
		private var _enabled : Boolean	=	true;
		
		public function get enabled() : Boolean
		{
			return _enabled;
		}
		
		public function set enabled( val : Boolean ) : void
		{
			_enabled		=	val;
			mouseChildren	=	val;
			mouseEnabled	=	val;			
		}
		
		//////////////////////////////////////////////////////
		
		/**
		 * 
		 * @return 
		 * 
		 */		
		public function get addToParent() : Boolean
		{
			return isAddToParent;
		}
			
		//////////////////////////////////////////////////////
		
		/**
		 * 
		 */		
		private var _invisibleForms:Array = new Array();
		
		/**
		 * 
		 * @param container
		 * 
		 */		
		public function setParentContainer( container : DisplayObjectContainer ) : void
		{			
			_parentContainer	=	container;
		}
		
		/**
		 * 
		 * @param
		 * 
		 */		
		public function addSubView( frm : SMUIBase, isShow : Boolean = true ) : void			
		{
			frm.coreSNSFramework	=	coreSNSFramework;
			frm.commandLayer		=	commandLayer;
			frm.modelLayer			=	modelLayer;
			frm.viewLayer			=	viewLayer;
			
			frm.setParentContainer( this );
			
			// Update view layer size at total
			if( frm.width > width )
				width	=	frm.width;
			
			if( frm.height > height )
				height	=	frm.height;			
			
			frm.onRegisterCompleted();
			
			if( isShow )
				showForm( frm );
			else
				_invisibleForms.push(frm);
		}
			
		/**
		 * Set visible or invisible by itseft
		 * @param isShow
		 * 
		 */		
		public function toggleVision( isShow : Boolean ) : void
		{
			if( _parentContainer != null )
			{
				if( _parentContainer is SMUIBase )
				{
					if( isShow )
						(_parentContainer as SMUIBase).showForm( this );
					
					else
						(_parentContainer as SMUIBase).hideForm( this );
				}
				else
				{
					try
					{ 
						if( isShow )
						{
							_parentContainer.addChild( this );
							onAddToParent( this );
							onShow();
							coreSNSFramework.invalidate();
						}
						
						else
						{
							_parentContainer.removeChild( this ); 
							onRemoveFromParent( this );							
							onHide();							
							coreSNSFramework.invalidate();
						}
						
					}
					catch( ex:* ){}
				}
			}
		}
		
		/**
		 * Add child form to display list
		 * @param frm
		 * 
		 */		
		public function showForm( frm : SMUIBase ) : void
		{			
			frm.onAddToParent( this );
			
			frm.onShow();
			
			coreSNSFramework.invalidate();
		}
		
		/**
		 * Remove child form from display list
		 * Caller is parent
		 * @param frm
		 * 
		 */		
		public function hideForm( frm : SMUIBase ) : void
		{
			if( ! contains( frm ) )
				return;
			
			frm.onRemoveFromParent( this );
			
			frm.onHide();
			
			coreSNSFramework.invalidate();
		}
		
		/**
		 * Remove or add child form to display list opposite to current state
		 * @param frm
		 * 
		 */		
		public function toggleForm( frm : SMUIBase ) : void
		{
			// Hide form if exist
			if( frm.parent == this )
				showForm( frm );
				
				// Or show if not
			else
				hideForm( frm );
			
			coreSNSFramework.invalidate();
		}
		
		/**
		 * 
		 * Ham nay co van de. _invisibleForms khong chinh xac
		 */		
		public function showAllInvisibleForms():void
		{
			var num :int = _invisibleForms.length;
			var frm:SMUIBase = null;
			for (var i : int = 0; i< num; ++i)
			{
				frm = _invisibleForms.pop();
				if(frm.parent == null)
				{
					showForm(frm);
				}
			}
		}
		
		/////////////////////////////////////////////////
		
		/**
		 * 
		 * @param w
		 * @param h
		 * 
		 */		
		public function setSize( w : Number, h : Number ) : void
		{
			// Sprites take the size that you draw in them
			var g : Graphics	=	this.graphics;
			g.beginFill( 0xFFFFFF, 0.0 );
			g.drawRect( 0, 0, w, h );
			g.endFill();
			
			coreSNSFramework.invalidate();
		}
		
		/**
		 * 
		 * @param x
		 * @param y
		 * 
		 */		
		public function setLocation( x : Number, y : Number ) : void
		{
			this.x	=	x;
			this.y	=	y;
			
			if( coreSNSFramework )
				coreSNSFramework.invalidate();
		}
				
		/**
		 * Call when XFramework force to add this object to flash render list
		 * @param parent : XFramework default host pointer
		 * 
		 */	
		public function onAddToParent( parent : DisplayObjectContainer ) : void
		{
			if( _parentContainer != parent )
				_parentContainer.addChild( this );
			
			else
				parent.addChild( this );
			
			isAddToParent	=	true;
		}
		
		/**
		 * Call when XFramework force to remove this object from flash render list 
		 * @param parent : XFramework default host pointer
		 * 
		 */						
		public function onRemoveFromParent( parent : DisplayObjectContainer ) : void
		{
			try
			{
				if( _parentContainer != parent )
					_parentContainer.removeChild( this );
				
				else
					parent.removeChild( this );
			}
			catch( ex : * )
			{}
			
			isAddToParent	=	false;
		}
		
		/////////////////////////////
		private var showTimes : int	=	0;
		
		/**
		 * 
		 * 
		 */		
		public function onFirstTimeShow() : void
		{
			
		}
		
		/**
		 * 
		 * 
		 */		
		public function onShow() : void
		{
			showTimes++;
			
			if( showTimes == 1 ) // First time
			{
				onFirstTimeShow();
				loadResource();
			}
		}		
		
		/**
		 * 
		 * 
		 */		
		public function onHide() : void
		{
			
		}
		
		/**
		 * 
		 * 
		 */		
		public function onRegisterCompleted() : void
		{
			
		}
		
		////////////////////////////////////////////////////////////
		// Implements auto load resource at first time technique
		
		private var forceResource : Array	=	new Array();
		
		/**
		 * Force to load resource at the first time onShow function is call
		 * @param bucket
		 * @param className
		 * @param func
		 * @param thisObject
		 * 
		 */		
		protected function registerResourceFunc( bucket : String, className : String, func : Function, thisObject : * = null ) : void
		{
			var res : Object	=	new Object();
			
			res.bucket			=	bucket;
			res.className		=	className;
			res.func			=	func;
			res.thisObject		=	thisObject;
			res.type			=	"function";
			
			forceResource.push( res );
		}
		
		/**
		 * Force to load resource at the first time onShow function is call
		 * @param bucket
		 * @param className
		 * @param obj
		 * 
		 */		
		protected function registerResource( bucket : String, className : String, obj : IResources ) : void
		{
			var res : Object	=	new Object();
			
			res.bucket			=	bucket;
			res.className		=	className;
			res.func			=	obj;
			res.type			=	"object";
			
			forceResource.push( res );
		}
		
		/**
		 * 
		 * 
		 */		
		protected function loadResource() : void
		{
			for( var key : String in forceResource )
			{
				var resObj : Object	=	forceResource[key];
				
				if( resObj.type == "function" )
					coreSNSFramework.resourceManager.getResourceFunc( resObj.bucket, resObj.className, resObj.func, resObj.thisObject );
				
				else if( resObj.type == "object" )
					coreSNSFramework.resourceManager.getResource( resObj.bucket, resObj.className, resObj.func );
			}
		}
		
		
	}
}